import Foundation

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public var val: Int
 *     public var next: ListNode?
 *     public init() { self.val = 0; self.next = nil; }
 *     public init(_ val: Int) { self.val = val; self.next = nil; }
 *     public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
 * }
 */

// 72ms
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
  if l1 == nil { return l2; }
  if l2 == nil { return l1; }

  let ln: ListNode = ListNode(0, nil);
  var p: ListNode? = ln;
  var carry: Int = 0;
  var ln1 = l1;
  var ln2 = l2;
  while(ln1 != nil || ln2 != nil) {
    let num1: Int = (ln1 == nil) ? 0 : ln1!.val;
    let num2: Int = (ln2 == nil) ? 0 : ln2!.val;
    let sum: Int = num1 + num2 + carry;
    carry = sum / 10;
    p!.next = ListNode(sum % 10);
    p = p!.next;
    if (ln1 != nil) { ln1 = ln1!.next ?? nil; }
    if (ln2 != nil) { ln2 = ln2!.next ?? nil; }
  }
  if (carry > 0) { p!.next = ListNode(carry); }
  return ln.next;
}

public class ListNode {
  public var val: Int
  public var next: ListNode?

  public init() { self.val = 0; self.next = nil; }
  public init(_ val: Int) { self.val = val; self.next = nil; }
  public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
}

func creatNode(_ list: [Int]) -> ListNode? {
  let length: Int = list.count
  if (length == 0) {
    return nil
  }
  var node: ListNode? = nil
  var p: ListNode? = nil
  for i in 0..<length {
    let value = list[length - i - 1]
    if (i == 0) {
      p = ListNode(value)
    } else {
      node = ListNode(value, p)
      p = node
    }    
  }
  return p;
}

func PrintNode(_ list: ListNode?) -> Void {
  if (list == nil) { return; }
  var node = list
  var p = "[" + String(node!.val)
  node = node!.next ?? nil
  while(node != nil) {
    p += ", " + String(node!.val)
    node = node!.next ?? nil
  }
  p += "]"
  print(p)
}

let testList : Array<Array<Int>> = [
  // [2,4,3],
  // [5,6,4]
  // ----
  // [9,9,9,9,9,9,9],
  // [9,9,9,9]
  // ----
  [0],
  [0]
]

let list1 = testList[0]
let list2 = testList[1]
// print(list1)
// print(list2)
let l1: ListNode? = creatNode(list1)
let l2: ListNode? = creatNode(list2)
PrintNode(l1)
PrintNode(l2)
let result: ListNode? = addTwoNumbers(l1, l2)
PrintNode(result)


